package com.zhangzhan.gulimallauthserver.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.zhangzhan.gulimallauthserver.feign.MemberFeignService;
import com.zhangzhan.gulimallauthserver.feign.PartyFeignService;
import com.zhangzhan.gulimallauthserver.vos.UserLoginVo;
import com.zhangzhan.gulimallauthserver.vos.UserRegisterVo;
import com.zhangzhan.gulimallcommcon.constant.SmsKey;
import com.zhangzhan.gulimallcommcon.tos.MemberTo;
import com.zhangzhan.gulimallcommcon.util.R;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.zhangzhan.gulimallcommcon.constant.AuthConstant.SESSION_USER_INFO_KEY;
import static com.zhangzhan.gulimallcommcon.exception.exception_enum.ExceptionEnum.VALID_SMS_TIME_EXCEPTION;

/**
 * @author 张一恒
 * @version 1.0
 * @description: 认证控制器
 * @date 2024/6/27 5:47
 */
@Controller
@RequestMapping("/auth")
public class AuthController {

    @Autowired
    private PartyFeignService partyFeignService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private MemberFeignService memberFeignService;

    /**
     * 发送手机验证码
     *
     * @param phone
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/send/sms", method = RequestMethod.GET)
    public R sendSms(@RequestParam("phone") String phone) {


        String codeValue = redisTemplate.opsForValue().get(SmsKey.KEY + phone);
        if (StrUtil.isNotBlank(codeValue)) {
            String expirationTime = codeValue.split("_")[1];
            if ((System.currentTimeMillis() - Long.parseLong(expirationTime)) <= 300000) {
                return R.error(VALID_SMS_TIME_EXCEPTION.getCode(), VALID_SMS_TIME_EXCEPTION.getMeg());
            }
        }

        String code = UUID.randomUUID().toString().substring(0, 5);
        R r = partyFeignService.sendSms(phone, code);

        redisTemplate.opsForValue().set(SmsKey.KEY + phone, code + "_" + System.currentTimeMillis(), 5, TimeUnit.MINUTES);

        return r;
    }



    /**
     * @param vo
     * @param result
     * @return com.zhangzhan.gulimallcommcon.util.R
     * @description 注册
     * @author zhangyiheng
     * @date 2024/6/27 23:16
     */
    @RequestMapping(value = "/enroll", method = RequestMethod.POST)
    public String enroll(@Validated UserRegisterVo vo, BindingResult result, RedirectAttributes attributes) {
        if (result.hasErrors()) {
            Map<String, String> map = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));

            attributes.addFlashAttribute("error", map);

            return "redirect:http://auth.gulimall.com/reg.html";
        } else {
            //注册
            //判断验证码
            String code = vo.getCode();
            String cacheCode = redisTemplate.opsForValue().get(SmsKey.KEY + vo.getPhone());
            if (StrUtil.isBlank(cacheCode) || StrUtil.isBlank(cacheCode.split("_")[0])) {
                attributes.addFlashAttribute("error", Map.of("code", "验证码不正确"));
                return "redirect:http://auth.gulimall.com/reg.html";
            } else {
                cacheCode = cacheCode.split("_")[0];
                if (code.equals(cacheCode)) {
                    //验证码正确
                    redisTemplate.delete(SmsKey.KEY + vo.getPhone());
                    //调用远程服务保存用户信息
                    BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
                    vo.setPassword(bCryptPasswordEncoder.encode(vo.getPassword()));
                    R r = memberFeignService.enrollUser(vo);
                    if (r.getCode() != 0) {
                        attributes.addFlashAttribute("msg", r.get("msg"));
                        return "redirect:http://auth.gulimall.com/reg.html";
                    }
                } else {
                    attributes.addFlashAttribute("error", Map.of("code", "验证码不正确"));
                    return "redirect:http://auth.gulimall.com/reg.html";
                }
            }

            return "redirect:http://auth.gulimall.com/login.html";
        }
    }

    /**
     * 登录
     *
     * @param
     * @return
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(@Validated UserLoginVo vo, BindingResult result, RedirectAttributes attributes, HttpSession httpSession) {

        if (result.hasErrors()) {
            Map<String, String> map = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));

            attributes.addFlashAttribute("error", map);

            return "redirect:http://auth.gulimall.com/login.html";
        }

        //调用远程服务校验
        R r = memberFeignService.login(vo);
        if (r.getCode() != 0) {
            attributes.addFlashAttribute("msg", r.get("msg"));
            return "redirect:http://auth.gulimall.com/login.html";
        }
        MemberTo memberTo = JSON.parseObject(r.getData(), MemberTo.class);
        httpSession.setAttribute(SESSION_USER_INFO_KEY, memberTo);

        return "redirect:http://gulimall.com";
    }

}
